//  @2022-07-31:基于extract_ccd290_16ch修改而来,用于处理浮点数的数据格式


#include "ccd290_extract.h"

void extract_ccd290_16ch_uint16( char bin_file[], 
                                 char fits_file[], 
                                 char key_file[],
                                 ccd290_config* cfg ) {

	printf("--> calling %s:%s\n", __FILE__, __func__);
    printf("--> reading binary data from: %s\n", bin_file);

    FILE *fb = fopen(bin_file,"rb");

    int bits_shift = 0;

    int num = cfg->LEN*CH_NUM + CH_NUM*bits_shift;	// total number of float
    uint16_t *regs = (uint16_t*)malloc(sizeof(uint16_t)*num);
    int num_chk = fread(regs, sizeof(uint16_t), num, fb);

    if( num_chk != num ){
    	printf("(%s:L:%d) Error in reading binary data: %s\n", __FILE__, __LINE__, bin_file);
    	printf("@ num_chk = %d\n", num_chk);
    	printf("@ num     = %d\n", num);
    	exit(0);
    }

    fclose(fb);
    printf("--> closed binary data file: %s\n", bin_file);

    uint16_t *OS1  = (uint16_t*)malloc(sizeof(uint16_t)*cfg->LEN);
    uint16_t *OS2  = (uint16_t*)malloc(sizeof(uint16_t)*cfg->LEN);
    uint16_t *OS3  = (uint16_t*)malloc(sizeof(uint16_t)*cfg->LEN);
    uint16_t *OS4  = (uint16_t*)malloc(sizeof(uint16_t)*cfg->LEN);

    uint16_t *OS5  = (uint16_t*)malloc(sizeof(uint16_t)*cfg->LEN);
    uint16_t *OS6  = (uint16_t*)malloc(sizeof(uint16_t)*cfg->LEN);
    uint16_t *OS7  = (uint16_t*)malloc(sizeof(uint16_t)*cfg->LEN);
    uint16_t *OS8  = (uint16_t*)malloc(sizeof(uint16_t)*cfg->LEN);

    uint16_t *OS9  = (uint16_t*)malloc(sizeof(uint16_t)*cfg->LEN);
    uint16_t *OS10 = (uint16_t*)malloc(sizeof(uint16_t)*cfg->LEN);
    uint16_t *OS11 = (uint16_t*)malloc(sizeof(uint16_t)*cfg->LEN);
    uint16_t *OS12 = (uint16_t*)malloc(sizeof(uint16_t)*cfg->LEN);

    uint16_t *OS13 = (uint16_t*)malloc(sizeof(uint16_t)*cfg->LEN);
    uint16_t *OS14 = (uint16_t*)malloc(sizeof(uint16_t)*cfg->LEN);
    uint16_t *OS15 = (uint16_t*)malloc(sizeof(uint16_t)*cfg->LEN);
    uint16_t *OS16 = (uint16_t*)malloc(sizeof(uint16_t)*cfg->LEN);

    int i, cnt=0;
    int i_start = CH_NUM*bits_shift;

    for(i=i_start; i<num; i+=CH_NUM) {

        OS1[cnt]  = regs[i+0];
        OS2[cnt]  = regs[i+1];
        OS3[cnt]  = regs[i+2];
        OS4[cnt]  = regs[i+3];
        
        OS5[cnt]  = regs[i+4];
        OS6[cnt]  = regs[i+5];
        OS7[cnt]  = regs[i+6];
        OS8[cnt]  = regs[i+7];

        OS9[cnt]  = regs[i+8];
        OS10[cnt] = regs[i+9];
        OS11[cnt] = regs[i+10];
        OS12[cnt] = regs[i+11];

        OS13[cnt] = regs[i+12];
        OS14[cnt] = regs[i+13];
        OS15[cnt] = regs[i+14];
        OS16[cnt] = regs[i+15];

        cnt++;
    }

//	CDS

    int N_ROW = cfg->N_ROW;
    int N_COL = cfg->N_COL;

    if( cfg->remove_preover_scan == 1 ){
        N_ROW = 4616;
        N_COL = 1152;
    }

    int pixel_num_total = N_ROW * N_COL * CH_NUM;
    printf("pixel_num_total = %d\n", pixel_num_total);
    printf("pixel_num_total/16 = %d\n", pixel_num_total/16);

    // float *ccd = (float*)malloc( sizeof(float) * pixel_num_total );
    uint16_t *ccd_uint16 = (uint16_t*)malloc( sizeof(uint16_t) * pixel_num_total );

    
    for( i = 0; i < pixel_num_total; i++ ) {
        // ccd[i]          = 0;
        ccd_uint16[i]   = 0;
    }

//  get offset from ccd290_config * cfg
	uint idx_offset = cfg->idx_offset;

    printf("idx_offset = %d\n", cfg->idx_offset);
    printf("cfg->LEN = %d\n", cfg->LEN);

//  开始拼接图像

    int row_cnt=0, col_cnt=0;
    int pix_idx;

    for( pix_idx = idx_offset; pix_idx < cfg->LEN; pix_idx += cfg->SAMP_NUM_PER_REG) {
    
    //  以下idx可以保证拼接完之后就是正常的图像,但是与邵立要求的数据格式存在一定的差异,调整idx的计算方式即可
        int idx_os1  = ( row_cnt * N_COL * (CH_NUM/2) ) + ( N_COL*0 + col_cnt-27*cfg->remove_preover_scan );
        int idx_os2  = ( row_cnt * N_COL * (CH_NUM/2) ) + ( N_COL*1 + col_cnt-27*cfg->remove_preover_scan );
        int idx_os3  = ( row_cnt * N_COL * (CH_NUM/2) ) + ( N_COL*2 + col_cnt-27*cfg->remove_preover_scan );
        int idx_os4  = ( row_cnt * N_COL * (CH_NUM/2) ) + ( N_COL*3 + col_cnt-27*cfg->remove_preover_scan );
        
        int idx_os5  = ( row_cnt * N_COL * (CH_NUM/2) ) + ( N_COL*5 - col_cnt - 1 +27*cfg->remove_preover_scan);
        int idx_os6  = ( row_cnt * N_COL * (CH_NUM/2) ) + ( N_COL*6 - col_cnt - 1 +27*cfg->remove_preover_scan);
        int idx_os7  = ( row_cnt * N_COL * (CH_NUM/2) ) + ( N_COL*7 - col_cnt - 1 +27*cfg->remove_preover_scan);
        int idx_os8  = ( row_cnt * N_COL * (CH_NUM/2) ) + ( N_COL*8 - col_cnt - 1 +27*cfg->remove_preover_scan);
        
        int idx_os9  = ( N_ROW*2 - row_cnt - 1 ) * N_COL * (CH_NUM/2) + ( N_COL*8 - col_cnt - 1 +27*cfg->remove_preover_scan);
        int idx_os10 = ( N_ROW*2 - row_cnt - 1 ) * N_COL * (CH_NUM/2) + ( N_COL*7 - col_cnt - 1 +27*cfg->remove_preover_scan);
        int idx_os11 = ( N_ROW*2 - row_cnt - 1 ) * N_COL * (CH_NUM/2) + ( N_COL*6 - col_cnt - 1 +27*cfg->remove_preover_scan);
        int idx_os12 = ( N_ROW*2 - row_cnt - 1 ) * N_COL * (CH_NUM/2) + ( N_COL*5 - col_cnt - 1 +27*cfg->remove_preover_scan);

        int idx_os13 = ( N_ROW*2 - row_cnt - 1 ) * N_COL * (CH_NUM/2) + ( N_COL*3 + col_cnt -27*cfg->remove_preover_scan);
        int idx_os14 = ( N_ROW*2 - row_cnt - 1 ) * N_COL * (CH_NUM/2) + ( N_COL*2 + col_cnt -27*cfg->remove_preover_scan);
        int idx_os15 = ( N_ROW*2 - row_cnt - 1 ) * N_COL * (CH_NUM/2) + ( N_COL*1 + col_cnt -27*cfg->remove_preover_scan);
        int idx_os16 = ( N_ROW*2 - row_cnt - 1 ) * N_COL * (CH_NUM/2) + ( N_COL*0 + col_cnt -27*cfg->remove_preover_scan);

        if( cfg->remove_preover_scan == 1 ) {
            if( (row_cnt < N_ROW) && (col_cnt >=27) && (col_cnt<1179) ) {

                ccd_uint16[idx_os1]    = OS1[pix_idx]  + cfg->cds_offset;
                ccd_uint16[idx_os2]    = OS2[pix_idx]  + cfg->cds_offset;
                ccd_uint16[idx_os3]    = OS3[pix_idx]  + cfg->cds_offset;
                ccd_uint16[idx_os4]    = OS4[pix_idx]  + cfg->cds_offset;
                ccd_uint16[idx_os5]    = OS5[pix_idx]  + cfg->cds_offset;
                ccd_uint16[idx_os6]    = OS6[pix_idx]  + cfg->cds_offset;
                ccd_uint16[idx_os7]    = OS7[pix_idx]  + cfg->cds_offset;
                ccd_uint16[idx_os8]    = OS8[pix_idx]  + cfg->cds_offset;
                ccd_uint16[idx_os9]    = OS9[pix_idx]  + cfg->cds_offset;
                ccd_uint16[idx_os10]   = OS10[pix_idx] + cfg->cds_offset;
                ccd_uint16[idx_os11]   = OS11[pix_idx] + cfg->cds_offset;
                ccd_uint16[idx_os12]   = OS12[pix_idx] + cfg->cds_offset;
                ccd_uint16[idx_os13]   = OS13[pix_idx] + cfg->cds_offset;
                ccd_uint16[idx_os14]   = OS14[pix_idx] + cfg->cds_offset;
                ccd_uint16[idx_os15]   = OS15[pix_idx] + cfg->cds_offset;
                ccd_uint16[idx_os16]   = OS16[pix_idx] + cfg->cds_offset;
            }

        } else {
            ccd_uint16[idx_os1]    = OS1[pix_idx]  + cfg->cds_offset;
            ccd_uint16[idx_os2]    = OS2[pix_idx]  + cfg->cds_offset;
            ccd_uint16[idx_os3]    = OS3[pix_idx]  + cfg->cds_offset;
            ccd_uint16[idx_os4]    = OS4[pix_idx]  + cfg->cds_offset;
            ccd_uint16[idx_os5]    = OS5[pix_idx]  + cfg->cds_offset;
            ccd_uint16[idx_os6]    = OS6[pix_idx]  + cfg->cds_offset;
            ccd_uint16[idx_os7]    = OS7[pix_idx]  + cfg->cds_offset;
            ccd_uint16[idx_os8]    = OS8[pix_idx]  + cfg->cds_offset;
            ccd_uint16[idx_os9]    = OS9[pix_idx]  + cfg->cds_offset;
            ccd_uint16[idx_os10]   = OS10[pix_idx] + cfg->cds_offset;
            ccd_uint16[idx_os11]   = OS11[pix_idx] + cfg->cds_offset;
            ccd_uint16[idx_os12]   = OS12[pix_idx] + cfg->cds_offset;
            ccd_uint16[idx_os13]   = OS13[pix_idx] + cfg->cds_offset;
            ccd_uint16[idx_os14]   = OS14[pix_idx] + cfg->cds_offset;
            ccd_uint16[idx_os15]   = OS15[pix_idx] + cfg->cds_offset;
            ccd_uint16[idx_os16]   = OS16[pix_idx] + cfg->cds_offset;            
        }
        
    	col_cnt++;  // 必须先+1,然后再进行判断

        if( col_cnt >= cfg->N_COL ) {
            col_cnt -= cfg->N_COL;
            row_cnt++;
        }
    }

//  ==============================================================================
//  创建fits文件
    fitsfile *fptr;
    int status=0;
    long fpixel = 1, naxis = 2, nelements;
    
    long naxes[2] = {(N_COL + cfg->HAS_TAG)*(CH_NUM/2), N_ROW * 2};
    
    if( cfg->include_line_num == 0 ){
    	naxes[0] = N_COL * (CH_NUM/2);
    	naxes[1] = N_ROW * 2;
    }

	fits_create_file(&fptr, fits_file, &status);
	
    fits_create_img(fptr, USHORT_IMG, naxis, naxes, &status);

//  ==============================================================================
    // 写入头文件信息
    add_fits_keywords_from_ini(fptr, key_file);
    
//	==============================================================================
//  写入图像数据
    nelements = naxes[0] * naxes[1];
    fits_write_img(fptr, TUSHORT, fpixel, nelements, ccd_uint16, &status);

//	==============================================================================
    fits_close_file(fptr, &status);
    fits_report_error(stderr, status);

//	===================================================
    free(OS1);
    free(OS2);
    free(OS3);
    free(OS4);

    free(OS5);
    free(OS6);
    free(OS7);
    free(OS8);

    free(OS9);
    free(OS10);
    free(OS11);
    free(OS12);

    free(OS13);
    free(OS14);
    free(OS15);
    free(OS16);

    free(regs);
    free(ccd_uint16);

    printf("--> data saved into fits: %s\n", fits_file);
}


